package cas;

import java.util.concurrent.CountDownLatch;

/**
 * @BelongsProject: concurrent
 * @BelongsPackage: cas
 * @Author: 江岸
 * @CreateTime: 2021-05-23 12:42
 * @Description: 手动实现简易CAS方法
 */
public class CasDemo {
    static volatile int count=0;

    public static void main(String[] args) throws InterruptedException {
        int threads = 100;
        CountDownLatch countDownLatch = new CountDownLatch(threads);
        for (int i=0;i<threads;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        for (int i=0;i<10;i++){
                            request();
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }finally {
                        countDownLatch.countDown();
                    }
                }
            }).start();
        }
        countDownLatch.await();
        System.out.println(Thread.currentThread().getName()+count);
    }

    /**
     *
     * count++ 拆解
     * 1. A = count
     * 2. B = A+1
     * 3.count = B 此处会出现并发问题。cas实现：
     *      1.获取锁
     *      2.获取count最新值，基座LV
     *      3.判断LV是否等于A，如果相等，则将B的值赋给count
     *      4.释放锁
     */
    public static void request() throws InterruptedException {
        //模拟耗时操作
        Thread.sleep(5);
        int exceptCount;//期望值
        while (!compareAndSwap((exceptCount=getCount()),exceptCount+1)){

        }
    }

    /**
     *
     * @param exceptCount 期望值
     * @param newCount 需要赋值的新值
     * @return
     */
    public static synchronized boolean compareAndSwap(int exceptCount,int newCount){
        //判断当前值是否和期望值一致，如果一致则可以更新新值
        if (getCount()==exceptCount){
            count = newCount;
            return true;
        }
        return false;
    }

    public static int getCount(){
        return count;
    }
}
